package com.cgnpc.scp.run.service.impl;

import cn.com.cgnpc.aep.bizcenter.appcenter.sdk.result.ApiResult;
import cn.com.cgnpc.aep.bizcenter.email.vo.SendEmails;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cgnpc.cud.core.domain.AjaxResult;
import com.cgnpc.cuddemo.utils.IDHelper;
import com.cgnpc.framework.service.IEmailCenterService;
import com.cgnpc.framework.userinfo.CurrentUser;
import com.cgnpc.framework.utils.HttpServlet;
import com.cgnpc.scp.common.bean.CreateFileInfo;
import com.cgnpc.scp.common.bean.MyPageResult;
import com.cgnpc.scp.common.mybatis.entity.ScpCommonFileUpload;
import com.cgnpc.scp.common.pojo.UserInfo;
import com.cgnpc.scp.common.service.AppConstantService;
import com.cgnpc.scp.common.utils.*;
import com.cgnpc.scp.manager.mybatis.entity.MessageTemplate;
import com.cgnpc.scp.manager.mybatis.mapper.client.MessageTemplateMapper;
import com.cgnpc.scp.manager.service.IMessageTemplateService;
import com.cgnpc.scp.manager.service.impl.MessageTemplateServiceImpl;
import com.cgnpc.scp.run.mybatis.entity.*;
import com.cgnpc.scp.run.mybatis.mapper.client.*;
import com.cgnpc.scp.run.pojo.ProjectImplementVo;
import com.cgnpc.scp.run.pojo.ProjectImplementationInfoVo;
import com.cgnpc.scp.run.pojo.ProjectUndertakeInfoVo;
import com.cgnpc.scp.run.service.ProjectInfoService;
import com.cgnpc.scp.run.utils.CommonExportUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.lang.reflect.Method;
import java.util.*;

/**********************************
 * 用途说明: 项目列表service
 * 作者姓名: zhangyibing
 * 创建时间: 2020年9月13日15:51:35
 ***********************************/
@Service("projectInfoService")
public class ProjectInfoServiceImpl implements ProjectInfoService {

    @Autowired
    private ProjectInfoMapper projectInfoMapper;

    @Autowired
    private ProjectMemberMapper projectMemberMapper;

    @Autowired
    private CurrentUser currentUser;

    @Autowired
    private ProjectImplementationImplementMapper projectImplementationImplementMapper;

    @Autowired
    private ProjectImplementationSummaryInfoMapper projectImplementationSummaryInfoMapper;

    @Autowired
    private ProjectWbsMapper projectWbsMapper;

    @Autowired
    private ProjectHtMapper projectHtMapper;

    @Autowired
    private ProjectImplementationWbsMapper projectImplementationWbsMapper;

    @Autowired
    private ProjectImplementationTeamMapper projectImplementationTeamMapper;

    @Autowired
    private IEmailCenterService iEmailCenterService;

    @Autowired
    private IMessageTemplateService messageTemplateService;

    @Autowired
    private AppConstantService appConstantService;

    @Autowired
    private SqlSession sqlSession;

    /**
     * 项目列表查询
     */
    @Override
    public MyPageResult<ProjectInfo> queryProjectInfoPageList(Map<String, Object> params) {
        MyPageResult<ProjectInfo> re = null;
        int pageNum = 1;
        int pageSize = 10;
        try {
            pageNum = Integer.parseInt(params.get("pageNum") + "");
            pageSize = Integer.parseInt(params.get("pageSize") + "");
        }catch (Exception e){
            e.printStackTrace();
        }
        Page<ProjectInfo> queryPage = PageHelper.startPage(pageNum, pageSize);

        projectInfoMapper.listPage(params);

        PageInfo<ProjectInfo> pageResult = new PageInfo<>(queryPage.getResult());
        re = MyPageResultUtil.createMyPageResult(pageResult);

        return re;
    }

    /**
     * 新增项目
     */
    @Override
    public AjaxResult saveProjectInfo(ProjectInfo projectInfo) {
        UserInfo currentUserDetail = currentUser.getCurrentUserDetail();
        String uuid = IDHelper.uuid();
        projectInfo.setId(uuid);
        projectInfo.setCreateUser(currentUserDetail.getUserId());
        projectInfo.setCreateUserName(currentUserDetail.getUserName());

        Date date = new Date();
        projectInfo.setCreateTime(date);
        projectInfo.setLastUpdateTime(date);
        //项目新建--同心圆取号阶段
        projectInfo.setProjectStage("1");

        projectInfoMapper.insert(projectInfo);

        return AjaxResult.success().put("data",projectInfo);
    }

    /**
     *  删除项目
     */
    @Override
    public AjaxResult remove(String id) {
        projectInfoMapper.deleteById(id);
        return AjaxResult.success();
    }

    @Override
    public AjaxResult getProjectInfoById(String id) {
        ProjectInfo info = projectInfoMapper.selectById(id);
        return AjaxResult.success().put("data", info);
    }

    @Override
    public AjaxResult updateProjectInfoById(ProjectInfo projectInfo) {
        projectInfoMapper.updateById(projectInfo);
        return AjaxResult.success();
    }

    @Override
    public String getStageIdByProjectId(String stageTableName, String projectId){
        List<String> stageIds = projectInfoMapper.getStageIdByProjectId(stageTableName, projectId);
        if(stageIds != null && stageIds.size() > 0){
            return stageIds.get(0);
        }
        return null;
    }

    @Override
    public ProjectUndertakeInfoVo getProjectUndertakeInfoById(String id) {
        ProjectUndertakeInfoVo result = new ProjectUndertakeInfoVo();
        ProjectInfo projectInfo = projectInfoMapper.selectById(id);
        result.setProjectInfo(projectInfo);

        setAttributeOfProject(result, ProjectTeam.class, "setProjectTeam", "tbl_run_project_team", id);
        setAttributeOfProject(result, ProjectReview.class, "setProjectReview", "tbl_run_project_review", id);
        //setAttributeOfProject(result, ProjectWbs.class, "setProjectWbs", "tbl_run_project_wbs", id);
        setAttributeOfProject(result, ProjectDirectorMaking.class, "setProjectDirectorMaking", "tbl_run_project_directormaking", id);
        setAttributeOfProject(result, ProjectTenderOffer.class, "setProjectTenderOffer", "tbl_run_project_tenderoffer", id);
//        setAttributeOfProject(result, ProjectHt.class, "setProjectHt", "tbl_run_project_ht", id);

        ProjectTeam team = result.getProjectTeam();
        if(team != null){
            team.setMembers(getMembersOfStage("tbl_run_project_team", id));
        }

        ProjectDirectorMaking directorMaking = result.getProjectDirectorMaking();
        if(directorMaking != null){
            String reportDataFileid = directorMaking.getReportDataFileid();
            String decisionmakingMeetingFileid = directorMaking.getDecisionmakingMeetingFileid();
            String wchldFileid = directorMaking.getWchldFileid();
            String jtjcjlFileid = directorMaking.getJtjcjlFileid();
            String jtjchyjyFileid = directorMaking.getJtjchyjyFileid();
            String signFileid = directorMaking.getSignFileid();
            Map<String, String> map = getFileNameMapByFileId(Arrays.asList(reportDataFileid, decisionmakingMeetingFileid, wchldFileid
            ,jtjcjlFileid, jtjchyjyFileid, signFileid));
            directorMaking.setReportDataFileName(map.get(reportDataFileid));
            directorMaking.setDecisionmakingMeetingFileName(map.get(decisionmakingMeetingFileid));
            directorMaking.setWchldFileName(map.get(wchldFileid));
            directorMaking.setJtjcjlFileName(map.get(jtjcjlFileid));
            directorMaking.setJtjchyjyFileName(map.get(jtjchyjyFileid));
            directorMaking.setSignFileName(map.get(signFileid));
        }

        ProjectTenderOffer projectTenderOffer = result.getProjectTenderOffer();
        if(projectTenderOffer != null){
            String bjsFileid = projectTenderOffer.getBjsFileid();
            String sycsbFileid = projectTenderOffer.getSycsbFileid();
            Map<String, String> map = getFileNameMapByFileId(Arrays.asList(bjsFileid, sycsbFileid));
            projectTenderOffer.setBjsFileName(map.get(bjsFileid));
            projectTenderOffer.setSycsbFileName(map.get(sycsbFileid));
        }

//        ProjectHt ht = result.getProjectHt();
        List<ProjectHt> ht = projectHtMapper.selectByPrimaryKeyWithDict(id);
        if(ht != null && ht.size() != 0){
            ProjectHt projectHt = ht.get(0);

            String contractFileid = projectHt.getContractFileid();
            Map<String, String> map = getFileNameMapByFileId(Arrays.asList(contractFileid));
            projectHt.setContractFileName(map.get(contractFileid));

            result.setProjectHt(projectHt);
        }

        ProjectReview review = result.getProjectReview();
        if(review != null){
            review.setMembers(getMembersOfStage("tbl_run_project_review", id));

            String reviewDataFileid = review.getReviewDataFileid();
            String meetingMinutes = review.getMeetingMinutes();
            Map<String, String> map = getFileNameMapByFileId(Arrays.asList(reviewDataFileid, meetingMinutes));
            review.setReviewDataFileName(map.get(reviewDataFileid));
            review.setMeetingMinutesFileName(map.get(meetingMinutes));
        }

        List<ProjectWbs> wbs = projectWbsMapper.selectByPrimaryKeyWithDict(id);
        if(wbs != null && wbs.size() != 0){
            ProjectWbs projectWbs = wbs.get(0);

            String wbssqFileId = projectWbs.getWbssqFileid();
            String yssqFileId = projectWbs.getYssqFileid();
            Map<String, String> map = getFileNameMapByFileId(Arrays.asList(wbssqFileId, yssqFileId));
            projectWbs.setWbssqFileName(map.get(wbssqFileId));
            projectWbs.setYssqFileName(map.get(yssqFileId));

            result.setProjectWbs(wbs.get(0));
        }
        return result;
    }

    @Override
    public ProjectImplementationInfoVo getProjectImplementationInfoById(String id) {
        ProjectImplementationInfoVo result = new ProjectImplementationInfoVo();
        ProjectInfo projectInfo = projectInfoMapper.selectById(id);
        result.setProjectInfo(projectInfo);

        setAttributeOfProject(result, ProjectImplementationTeam.class, "setProjectImplementationTeam", "tbl_run_implementation_team", id);
        setAttributeOfProject(result, ProjectImplementationShuxing.class, "setProjectImplementationShuxing", "tbl_run_implementation_shuxing", id);
        setAttributeOfProject(result, ProjectImplementationWbs.class, "setProjectImplementationWbs", "tbl_run_implementation_wbs", id);
        setAttributeOfProject(result, ProjectImplementationSummary.class, "setProjectImplementationSummary", "tbl_run_implementation_summary", id);

        List<ProjectImplementationImplement> implementList = projectImplementationImplementMapper.selectList(new QueryWrapper<ProjectImplementationImplement>()
        .select("*","(select file_center_file_name from tbl_common_fileupload tcf where tcf.file_center_file_id = tbl_run_implementation_implement.yszs) as yszs_file_name")
        .eq("projectid", id));
        ProjectImplementVo projectImplementationImplement = new ProjectImplementVo();
        projectImplementationImplement.setProjectSummaryRequirement(projectInfo.getProjectSummaryRequirement());
        projectImplementationImplement.setImplementList(implementList);
        result.setProjectImplementationImplement(projectImplementationImplement);

        List<ProjectImplementationSummaryInfo> summaryInfoList = projectImplementationSummaryInfoMapper.selectList(new QueryWrapper<ProjectImplementationSummaryInfo>()
                .select("*"
                ,"(select file_center_file_name from tbl_common_fileupload tcf where tcf.file_center_file_id = tbl_run_implementation_summaryinfo.yszs) as yszs_file_name"
                ,"(select file_center_file_name from tbl_common_fileupload tcf where tcf.file_center_file_id = tbl_run_implementation_summaryinfo.zfsqh) as zfsqh_file_name")
                .eq("projectid", id));
        result.setSummaryInfoList(summaryInfoList);

        ProjectImplementationTeam team = result.getProjectImplementationTeam();
        if(team != null){
            team.setMembers(getMembersOfStage("tbl_run_implementation_team", id));
        }

        List<ProjectImplementationWbs> wbs = projectImplementationWbsMapper.selectByPrimaryKeyWithDict(id);
        if(wbs != null && wbs.size() != 0){
            ProjectImplementationWbs projectWbs = wbs.get(0);

            String wbssqFileId = projectWbs.getWbssqFileid();
            String yssqFileId = projectWbs.getYssqFileid();
            String htFileid = projectWbs.getHtFileid();
            String sycsbFileid = projectWbs.getSycsbFileid();
            Map<String, String> map = getFileNameMapByFileId(Arrays.asList(wbssqFileId, yssqFileId, htFileid, sycsbFileid));
            projectWbs.setWbssqFileName(map.get(wbssqFileId));
            projectWbs.setYssqFileName(map.get(yssqFileId));
            projectWbs.setHtFileName(map.get(htFileid));
            projectWbs.setSycsbFileName(map.get(sycsbFileid));

            result.setProjectImplementationWbs(wbs.get(0));
        }

        ProjectImplementationSummary summary = result.getProjectImplementationSummary();
        if(summary != null){
            String summaryFileid = summary.getSummaryFileid();
            Map<String, String> map = getFileNameMapByFileId(Arrays.asList(summaryFileid));
            summary.setSummaryFileName(map.get(summaryFileid));
        }

        ProjectImplementationShuxing shuxing = result.getProjectImplementationShuxing();
        if(shuxing != null){
            String xmsxrdFileid = shuxing.getXmsxrdFileid();
            Map<String, String> map = getFileNameMapByFileId(Arrays.asList(xmsxrdFileid));
            shuxing.setXmsxrdFileName(map.get(xmsxrdFileid));
        }

        return result;
    }

    @Override
    public CreateFileInfo exportExcel(Map<String, Object> params) throws Exception {
        CreateFileInfo createFileInfo;

        try {
            List<String> titleList = Arrays.asList(
                    "项目编码","项目名称","客户名称"
                    ,"合同编码","合同名称","承揽负责人","项目经理","项目阶段"
                    ,"市场机会","信息来源"
            );
            List<String> fields = Arrays.asList("projectCode","projectName", "marketCustomerName"
                    ,"contractCode","contractName","leadingManName","projectManagerName","projectStageName"
                    ,"marketInfoName","messageFunds"
            );

            CommonExportUtil<ProjectInfo> util = new CommonExportUtil<>();
            createFileInfo = util.exportExcel(appConstantService, sqlSession, titleList, fields
                    , "com.cgnpc.scp.run.mybatis.mapper.client.ProjectInfoMapper"
                    ,"listPageExport", params);
        } catch (Exception e) {
            throw e;
        }

        return createFileInfo;
    }

    @Override
    public Boolean importFromExcel(MultipartFile file) throws IOException {
        InputStream is = file.getInputStream();
        List<ProjectInfo> projectInfoList = new ArrayList<>();
        try{
            Workbook workbook = WorkbookFactory.create(is);
            handleExcel(projectInfoList,workbook);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            is.close();
        }
        projectInfoList.forEach( info -> {
            projectInfoMapper.insert(info);
        });
        return true;
    }

    /**********************************
     * 用途说明: 处理excel
     * 参数说明 file
     * 返回值说明:
     ***********************************/
    void handleExcel(List<ProjectInfo> projectInfoList, Workbook workbook) throws Exception{
        if(workbook == null){
            throw new Exception("Excel工作簿为空！");
        }
        Sheet sheet = null;
        Row row = null;
        Cell cell = null;
        for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
            sheet = workbook.getSheetAt(i);
            if (sheet == null) {
                continue;
            }
            int sheetNum = sheet.getLastRowNum();
            if(sheetNum < 8){
                throw new Exception("导入数据为空");
            }
            //遍历当前sheet中的所有行
            for (int j = 8; j <= sheetNum ; j++) {
                row = sheet.getRow(j);
                if (row == null ) {
                    continue;
                }
                ProjectInfo info = new ProjectInfo();
                //把每个单元格的值付给对象的对应属性
                if(row.getCell(0) != null){
                    info.setProjectCode(row.getCell(0).toString());
                }else{
                    throw new Exception("导入的第"+(j + 1)+"行中项目编码不存在");
                }
                if(row.getCell(1) != null){
                    info.setProjectName(row.getCell(1).toString());
                }else{
                    throw new Exception("导入的第"+(j + 1)+"行中项目名称不存在");
                }
                if(row.getCell(2) != null){
                    info.setProjectName(row.getCell(2).toString());
                }
                info.setId(IDHelper.uuid());
                info.setCreateTime(new Date());
                projectInfoList.add(info);
            }
        }
    }

    /**********************************
     * 用途说明: 下载导入模板
     * 参数说明 file
     * 返回值说明:
     ***********************************/
    @Override
    public void uploadTemp() throws IOException {
        //两种方式 1、自己构建excel 2、下载对应的模板
        OutputStream out = null;
        InputStream inputStream = null;
        byte[] buff = new byte[2048];
        try{
            String path = this.getClass().getClassLoader().getResource("").getPath();
            File file = new File(path+"upfileTemplate/调试经营管理-项目列表导入模板.xlsx");
            file = FileUtil.formatSafeFileWithDownloadFile(file);
            inputStream = new FileInputStream(file);
            String filename=file.getName();
            filename= XSSFilterUtils.cleanXSS(file.getName());
            HttpServletResponse response = HttpServlet.getResponse();
            out = response.getOutputStream();
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            //前端好像获取不到filename
            response.setHeader("Content-Disposition", "attachment;filename="+ new String("调试经营管理-项目列表导入模板.xlsx".getBytes("utf-8"), "ISO8859-1"));
            int num = -1;
            while((num = inputStream.read(buff)) != -1){
                out.write(buff,0,num);
            }
            out.flush();
            out.close();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(inputStream != null){
                inputStream.close();
            }
            if(out != null){
                out.flush();
                out.close();
            }
        }
    }

    private void setAttributeOfProject(Object vo, Class clazz, String methodName, String tableName, String projectId){
        List<Map<String, Object>> stageList = projectInfoMapper.getStageMapByProjectId(tableName, projectId);
        try{
            if(stageList != null && stageList.size() > 0){
                Map<String, Object> stageMap = stageList.get(0);
                Object obj = clazz.newInstance();
                BeanUtils.populate(obj, stageMap);
                Class voClazz = vo.getClass();
                Method method = voClazz.getDeclaredMethod(methodName, clazz);
                method.invoke(vo, obj);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }



    private List<ProjectMember> getMembersOfStage(String stageName, String projectId){
        return projectMemberMapper.selectList(new QueryWrapper<ProjectMember>()
        .eq("projectid", projectId)
        .eq("stage_table_name", stageName));
    }


    private Map<String, String> getFileNameMapByFileId(List<String> fileIds){
        List<ScpCommonFileUpload> files = projectInfoMapper.getFileNameMapByFileId(fileIds);
        Map<String, String> map = new HashMap<>();
        if(files != null && files.size() != 0){
            for(ScpCommonFileUpload file : files){
                map.put(file.getFileCenterFileId(), file.getFileCenterFileName());
            }
        }
        return map;
    }

    @Override
    public ApiResult notifyBusiness(String projectId) throws Exception {
        if(StringUtil.isNullOrSpace(projectId)){
            return null;
        }
        //tbl_run_implementation_team
        List<ProjectImplementationTeam> teams = projectImplementationTeamMapper.selectList(new QueryWrapper<ProjectImplementationTeam>()
                .eq("projectid", projectId));
        if(teams == null || teams.size() == 0){
            return null;
        }
        ProjectInfo project = projectInfoMapper.selectById(projectId);
        if(project == null){
            return null;
        }
        ProjectImplementationTeam team = teams.get(0);
        String user = team.getBusinessManager();
        String[] sendTo = new String[]{user};
        String template = messageTemplateService.getTsjy_xmjd();
        Map<String, String> param = new HashMap<>();
        param.put("title",project.getProjectName());
        String content = FreemarkerUtil.render(param, template);
        //调用发送邮件服务
        SendEmails emails = iEmailCenterService.buildSendEmails(CurrentUser.getUser(),
                null,content,"",
                sendTo,content);

        return iEmailCenterService.sendEmail(emails);
    }
}
